<!-- 我的地图 -->

<template>
  <div class="MyMap">
    <div ref="map" class="MyMap-render" />

    <div class="MyMap-floor">
      <div
        v-for="item in floors"
        :key="item.id"
        :class="{ 'floor-current': current === item.id }"
        @click="changeFloor(item.id)"
      >
        {{ item.name }}
      </div>
    </div>
  </div>
</template>

<script>
// ============================== 导入依赖 ============================== //

import CORE from '@/CORE'
import CONST from './CONST'

const { Engine } = window

// ============================== 导出组件 ============================== //

export default {
  /**
   * 名称定义 (实际使用名称)
   */
  name: 'MyMap',

  /**
   * 混入列表 (配置选项合并)
   */
  mixins: [CORE.mixInfo(), CORE.mixOne(), CORE.mixSelect()],

  /**
   * 状态数据 (函数返回对象)
   */
  data() {
    return {
      engine: null, // 地图引擎
      layerID: 1, // 图层 ID
      current: CONST.FLOOR_OUTER[1].id, // 当前楼层
      popId: '', // 气泡 ID
    }
  },

  /**
   * 计算属性 (慎用箭头函数)
   */
  computed: {
    /**
     * 楼层列表
     */
    floors() {
      const { point = [] } = this.info
      const { subSystemId } = this.infoParam
      return CONST.FLOOR_OUTER.map((floor) => {
        const hideList = point.filter((item) => floor.id !== item.site.floor || item.subSystemId !== subSystemId)
        const showList = point.filter((item) => floor.id === item.site.floor && item.subSystemId === subSystemId)
        return {
          ...floor,
          deviceHide: hideList.map((item) => item.deviceId),
          deviceShow: showList.map((item) => item.deviceId),
        }
      })
    },

    /**
     * 正在增加的子系统 ID
     */
    addSystemId() {
      const { isAdd, one, param } = this
      return isAdd && one.deviceId ? param.subSystemId : ''
    },
  },

  /**
   * 监听属性 (深度 deep 首次 immediate)
   */
  watch: {
    /**
     * 监听子系统
     */
    infoType() {
      this.changeFloor(this.current)
    },

    /**
     * 监听单项
     */
    one({ device }) {
      this.engine.Api.Camera.lookAt({
        objType: this.layerID,
        id: device.deviceId,
        click: true,
        offset: new this.engine.Api.Type.Vector3(0, 0, 30),
        time: 0.5,
      })
    },

    /**
     * 监听信息就绪
     */
    async readyInfo(ready) {
      if (ready) {
        this.delLayer()
        await this.$nextTick()
        this.addLayer()

        this.addModelList()
        await this.$nextTick()
        // this.addPopList()

        this.changeFloor(this.current)
      }
    },

    /**
     * 监听单项，隐藏气泡
     */
    // 'one.id'(id) {
    //   const { popId } = this
    //   const popDiv = document.getElementsByClassName('MyMap-pop')
    //   if (popId && popId !== id && popDiv && popDiv.length) popDiv[0].style.display = 'none'
    // },
  },

  /**
   * 挂载完成 (先抽取再调用)
   */
  mounted() {
    this.initEngine()
  },

  /**
   * 销毁之前 (先抽取再调用)
   */
  beforeDestroy() {
    this.engine.dispose()
  },

  /**
   * 本地方法 (轻量重要在前)
   */
  methods: {
    /**
     * 初始化引擎
     */
    initEngine() {
      const engine = new Engine({ ...CONST.ENGINE, dom: this.$refs.map })
      this.engine = engine

      engine.open()

      engine.on('EngineFinish', () => this.changeFloor(CONST.FLOOR_OUTER[0].id))

      engine.on('MeshClick', (geo) => {
        const { layerID, selectParam, infoType, $store } = this
        const [layer, id] = geo.split(':')
        if (`${layerID}` === layer) {
          selectParam.deviceId = id
          $store.commit(`${infoType}/openNewOneShow`, { id })
        }
      })
    },

    /**
     * 飞往目标
     */
    flyTo(point, target, time = 0) {
      const { Type, Camera } = this.engine.Api
      Camera.flyTo({
        point: new Type.Vector3(...point),
        target: new Type.Vector3(...target),
        time,
      })
    },

    /**
     * 切换楼层
     */
    changeFloor(id) {
      const floor = this.floors.find((item) => item.id === id)
      this.current = floor.id

      const { MeshInfo } = this.engine.Api
      MeshInfo.setVisible({ objType: CONST.DEFAULT, id: floor.hide, visible: false })
      MeshInfo.setVisible({ objType: CONST.DEFAULT, id: floor.show, visible: true })
      MeshInfo.setVisible({ objType: this.layerID, id: floor.deviceHide, visible: false })
      MeshInfo.setVisible({ objType: this.layerID, id: floor.deviceShow, visible: true })

      this.flyTo(floor.point, floor.target, 1)
    },

    /**
     * 添加图层
     */
    addLayer() {
      const { Layers } = this.engine.Api
      Layers.addLayer({ ...CONST.LAYER, id: this.layerID })
    },

    /**
     * 删除图层
     */
    delLayer() {
      const { Layers } = this.engine.Api
      Layers.removeLayer({ id: this.layerID })
      this.layerID++ // 更新图层 ID
    },

    /**
     * 添加模型列表
     */
    async addModelList() {
      const { engine, info } = this
      info.point.forEach((item) => {
        const { deviceId: id, deviceName: name, longitude: x, latitude: y, elevation: z, site } = item
        const shape = new this.engine.Api.Type.Vector3(Number(x), Number(y), Number(z))
        const userData = { ...CONST.MODEL, id, name, assetPath: site.icon, shapes: [shape] }
        engine.Api.Models.addModel({ objType: this.layerID, modelType: 'Obj', userData })
      })
    },

    /**
     * 添加气泡列表
     */
    async addPopList() {
      const { engine, info } = this
      info.point.forEach((item) => {
        const { deviceId: id, deviceName: name } = item
        engine.Api.Pop.setPop({ objType: this.layerID, id }, (result) => {
          this.popId = id

          const panelDiv = document.createElement('div')
          const nameDiv = document.createElement('div')
          const areaDiv = document.createElement('div')
          const delBtn = document.createElement('button')
          panelDiv.className = 'MyMap-pop'
          nameDiv.innerText = name
          // areaDiv.innerText = treeMap[areaId].nameList.join(' > ')
          delBtn.innerText = '删除'
          delBtn.onclick = () => {
            // this.setModal('del')
            // this.startDel()
          }
          panelDiv.appendChild(nameDiv)
          panelDiv.appendChild(areaDiv)
          panelDiv.appendChild(delBtn)
          result.appendChild(panelDiv)
        })
      })
    },
  },
}
</script>

<style lang="scss">
@import './index.scss';
</style>
